﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Web.UI;
using System.Text;

namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// Ext.form.FormPanel are classes derived from Panel and the library provides two ways to build a form: BasicForm and FormPanel.
    /// </summary>    
    public class ExtFormPanel : ExtComponent  
    {
        private List<ExtComponent> _items = new List<ExtComponent>();
        private List<ExtComponent> _buttons = new List<ExtComponent>();
        private List<ScriptReference> _references = new List<ScriptReference>();

        public override List<ScriptReference> GetScriptReferences()
        {
            return base.GetScriptReferences();
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.form.FormPanel";

            String[] properties = new String[]{
                "border", "bodyStyle"         
            };

            Type component = typeof(ExtFormPanel);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'ExtFormPanel.{0}'", property));

                Object value = i.GetValue(this, null);

                if (value == null)
                {
                    continue;
                }

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }

            //add items
            if (items.Count != 0)
            {
                // build items list
                StringBuilder itemList = new StringBuilder("[");

                for (int i = 0; i < items.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        itemList.Append(",");
#if DEBUG
                        itemList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = items[i].GetScriptDescriptors();

                    // get the items's list of script dependencies
                    List<ScriptReference> references = items[i].GetScriptReferences();

                    // make sure the script dependencies are registered
                    _references.AddRange(references);

                    // write the item's config to the list
                    itemList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                itemList.Append("]");

                desc.AddPropertyBase("items", itemList);
            }

            //add items
            if (buttons != null && buttons.Count != 0)
            {
                // build items list
                StringBuilder itemList = new StringBuilder("[");

                for (int i = 0; i < buttons.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        itemList.Append(",");
#if DEBUG
                        itemList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = buttons[i].GetScriptDescriptors();

                    // get the items's list of script dependencies
                    List<ScriptReference> references = buttons[i].GetScriptReferences();

                    // make sure the script dependencies are registered
                    _references.AddRange(references);

                    // write the item's config to the list
                    itemList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                itemList.Append("]");

                desc.AddPropertyBase("buttons", itemList);
            }


            return list;
        }

        #region Public Properties

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual List<ExtComponent> items
        {
            get
            {
                return _items;
            }
        }

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual List<ExtComponent> buttons
        {
            get
            {
                return _buttons;
            }
        }

        public String bodyStyle { get; set; }

        public Boolean border { get; set; }

        /// <summary>
        /// A CSS style specification string to add to each field element in this layout (defaults to '').
        /// </summary>
        [Description("A CSS style specification string to add to each field element in this layout (defaults to '').")]
        public String elementStyle { get; set; }

        /// <summary>
        /// The standard separator to display after the text of each form label (defaults to a colon ':'). To turn off separators for all fields in this layout by default specify empty string '' (if the labelSeparator value is explicitly set at the field level, those will still be displayed).
        /// </summary>
        [Description("The standard separator to display after the text of each form label (defaults to a colon ':'). To turn off separators for all fields in this layout by default specify empty string '' (if the labelSeparator value is explicitly set at the field level, those will still be displayed).")]
        public String labelSeparator { get; set; }

        /// <summary>
        /// A CSS style specification string to add to each field label in this layout (defaults to '').
        /// </summary>
        [Description("A CSS style specification string to add to each field label in this layout (defaults to '').")]
        public String labelStyle { get; set; }

        [Description("True to hide field labels by default (defaults to false).")]
        public Boolean? hideLabels { get; set; }

        [Description("A CSS class to add to the div wrapper that contains each field label and field element (the default class is 'x-form-item' and itemCls will be added to that)")]
        public String itemCls { get; set; }

        [Description("The default padding in pixels for field labels (defaults to 5). labelPad only applies if labelWidth is also specified, otherwise it will be ignored.")]
        public int labelPad { get; set; }

        [Description("The default width in pixels of field labels (defaults to 100).")]
        public Unit labelWidth { get; set; }        

        #endregion
    }
}
